package com.wxl.asmgradleplugin.myplugin

import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.commons.AdviceAdapter

class LogMethodVisitor(
    private val className: String?,
    api: Int, mv: MethodVisitor?, access: Int, private val methodName: String?, desc: String?
) : AdviceAdapter(api, mv, access, methodName, desc) {
    private val addClass = "com/wxl/asmgradleplugin/demo/asm/LogUtil"
    override fun visitCode() {
        super.visitCode()
        println("====111 visitCode: $methodName")
        if ("test" == methodName) {
            // 在方法开始处插入LogUtil.refreshTime()
            mv.visitLdcInsn(className)
            mv.visitLdcInsn(methodName)
            mv.visitMethodInsn(
                Opcodes.INVOKESTATIC,
                addClass,
                "refreshTime",
                "(Ljava/lang/String;Ljava/lang/String;)V",
                false
            )
        }
    }

    override fun visitInsn(opcode: Int) {
        println("====111 visitInsn: $methodName")
        if ("test" == methodName) {
            // 在方法返回之前插入LogUtil.calFuncTime(packageName, methodName)
            if (//IRETURN（Opcodes.IRETURN）: 返回整数。
            //LRETURN（Opcodes.LRETURN）: 返回长整数。
            //FRETURN（Opcodes.FRETURN）: 返回浮点数。
            //DRETURN（Opcodes.DRETURN）: 返回双精度浮点数。
            //ARETURN（Opcodes.ARETURN）: 返回对象引用。
            //RETURN（Opcodes.RETURN）: 用于返回void。
                (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) //这部分检查当前指令是否是ATHROW，即抛出异常指令。
                || opcode == Opcodes.ATHROW
            ) {
                mv.visitLdcInsn(className)
                mv.visitLdcInsn(methodName)
                mv.visitMethodInsn(
                    Opcodes.INVOKESTATIC,
                    addClass,
                    "calFuncTime",
                    "(Ljava/lang/String;Ljava/lang/String;)V",
                    false
                )
            }
        }
        super.visitInsn(opcode)
    }

}